home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / filesyst / ext2 / ext2ed-0.000 / ext2ed-0 / ext2ed-0.1 / file_com.c < prev    next >
C/C++ Source or Header  |  1995-08-24  |  13KB  |  565 lines

  1. /*
  2.  
  3. /usr/src/ext2ed/file_com.c
  4.  
  5. A part of the extended file system 2 disk editor.
  6.  
  7. ----------------------------
  8. Commands which handle a file
  9. ----------------------------
  10.  
  11. First written on: April 18 1995
  12.  
  13. Copyright (C) 1995 Gadi Oxman
  14.  
  15. */
  16.  
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20.  
  21. #include "ext2ed.h"
  22.  
  23. int init_file_info (void)
  24.  
  25. {
  26.     struct ext2_inode *ptr;
  27.     
  28.     ptr=&type_data.u.t_ext2_inode;
  29.     
  30.     file_info.inode_ptr=ptr;
  31.     file_info.inode_offset=device_offset;
  32.  
  33.     file_info.global_block_num=ptr->i_block [0];
  34.     file_info.global_block_offset=ptr->i_block [0]*file_system_info.block_size;
  35.     file_info.block_num=0;
  36.     file_info.blocks_count=(ptr->i_size+file_system_info.block_size-1)/file_system_info.block_size;
  37.     file_info.file_offset=0;
  38.     file_info.file_length=ptr->i_size;
  39.     file_info.level=0;
  40.     file_info.offset_in_block=0;
  41.     
  42.     file_info.display=HEX;
  43.  
  44.     low_read (file_info.buffer,file_system_info.block_size,file_info.global_block_offset);
  45.     
  46.     return (1);
  47. }
  48.  
  49.  
  50. void type_file___inode (char *command_line)
  51.  
  52. {
  53.     dispatch ("settype ext2_inode");
  54. }
  55.  
  56. void type_file___show (char *command_line)
  57.  
  58. {
  59.     if (file_info.display==HEX)
  60.         file_show_hex ();
  61.     if (file_info.display==TEXT)
  62.         file_show_text ();
  63. }
  64.  
  65. void type_file___nextblock (char *command_line)
  66.  
  67. {
  68.     long block_offset=1;
  69.     char *ptr,buffer [80];
  70.  
  71.     ptr=parse_word (command_line,buffer);
  72.     
  73.     if (*ptr!=0) {
  74.         ptr=parse_word (ptr,buffer);
  75.         block_offset*=atol (buffer);
  76.     }
  77.  
  78.     if (file_info.block_num+block_offset >= file_info.blocks_count) {
  79.         wprintw (command_win,"Error - Block offset out of range\n");wrefresh (command_win);
  80.         return;
  81.     }
  82.     
  83.     file_info.block_num+=block_offset;
  84.     file_info.global_block_num=file_block_to_global_block (file_info.block_num,&file_info);
  85.     file_info.global_block_offset=file_info.global_block_num*file_system_info.block_size;
  86.     file_info.file_offset=file_info.block_num*file_system_info.block_size;
  87.  
  88.     low_read (file_info.buffer,file_system_info.block_size,file_info.global_block_offset);
  89.  
  90.     strcpy (buffer,"show");dispatch (buffer);
  91. }
  92.  
  93. void type_file___next (char *command_line)
  94.  
  95. {
  96.     int offset=1;
  97.     char *ptr,buffer [80];
  98.  
  99.     ptr=parse_word (command_line,buffer);
  100.     
  101.     if (*ptr!=0) {
  102.         ptr=parse_word (ptr,buffer);
  103.         offset*=atol (buffer);
  104.     }
  105.     
  106.     if (file_info.offset_in_block+offset < file_system_info.block_size) {
  107.         file_info.offset_in_block+=offset;
  108.         sprintf (buffer,"show");dispatch (buffer);
  109.     }
  110.         
  111.     else {
  112.         wprintw (command_win,"Error - Offset out of block\n");refresh_command_win ();
  113.     }
  114. }
  115.  
  116. void type_file___offset (char *command_line)
  117.  
  118. {
  119.     unsigned long offset;
  120.     char *ptr,buffer [80];
  121.  
  122.     ptr=parse_word (command_line,buffer);
  123.     
  124.     if (*ptr!=0) {
  125.         ptr=parse_word (ptr,buffer);
  126.         offset=atol (buffer);
  127.     }
  128.     else {
  129.         wprintw (command_win,"Error - Argument not specified\n");refresh_command_win ();
  130.         return;
  131.     }
  132.     
  133.     if (offset < file_system_info.block_size) {
  134.         file_info.offset_in_block=offset;
  135.         sprintf (buffer,"show");dispatch (buffer);
  136.     }
  137.  
  138.     else {
  139.         wprintw (command_win,"Error - Offset out of block\n");refresh_command_win ();
  140.     }
  141. }
  142.  
  143. void type_file___prev (char *command_line)
  144.  
  145. {
  146.     int offset=1;
  147.     char *ptr,buffer [80];
  148.  
  149.     ptr=parse_word (command_line,buffer);
  150.     
  151.     if (*ptr!=0) {
  152.         ptr=parse_word (ptr,buffer);
  153.         offset*=atol (buffer);
  154.     }
  155.     
  156.     if (file_info.offset_in_block-offset >= 0) {
  157.         file_info.offset_in_block-=offset;
  158.         sprintf (buffer,"show");dispatch (buffer);
  159.     }
  160.     
  161.     else {
  162.         wprintw (command_win,"Error - Offset out of block\n");refresh_command_win ();
  163.     }
  164. }
  165.  
  166. void type_file___prevblock (char *command_line)
  167.  
  168. {
  169.     long block_offset=1;
  170.     char *ptr,buffer [80];
  171.  
  172.     ptr=parse_word (command_line,buffer);
  173.     
  174.     if (*ptr!=0) {
  175.         ptr=parse_word (ptr,buffer);
  176.         block_offset*=atol (buffer);
  177.     }
  178.  
  179.     if (file_info.block_num-block_offset < 0) {
  180.         wprintw (command_win,"Error - Block offset out of range\n");wrefresh (command_win);
  181.         return;
  182.     }
  183.     
  184.     file_info.block_num-=block_offset;
  185.     file_info.global_block_num=file_block_to_global_block (file_info.block_num,&file_info);
  186.     file_info.global_block_offset=file_info.global_block_num*file_system_info.block_size;
  187.     file_info.file_offset=file_info.block_num*file_system_info.block_size;
  188.  
  189.     low_read (file_info.buffer,file_system_info.block_size,file_info.global_block_offset);
  190.  
  191.     strcpy (buffer,"show");dispatch (buffer);
  192. }
  193.  
  194. void type_file___block (char *command_line)
  195.  
  196. {
  197.     long block_offset=1;
  198.     char *ptr,buffer [80];
  199.  
  200.     ptr=parse_word (command_line,buffer);
  201.     
  202.     if (*ptr==0) {
  203.         wprintw (command_win,"Error - Invalid arguments\n");wrefresh (command_win);
  204.         return;
  205.     }
  206.     
  207.     ptr=parse_word (ptr,buffer);
  208.     block_offset=atol (buffer);
  209.  
  210.     if (block_offset < 0 || block_offset >= file_info.blocks_count) {
  211.         wprintw (command_win,"Error - Block offset out of range\n");wrefresh (command_win);
  212.         return;
  213.     }
  214.  
  215.     file_info.block_num=block_offset;
  216.     file_info.global_block_num=file_block_to_global_block (file_info.block_num,&file_info);
  217.     file_info.global_block_offset=file_info.global_block_num*file_system_info.block_size;
  218.     file_info.file_offset=file_info.block_num*file_system_info.block_size;
  219.  
  220.     low_read (file_info.buffer,file_system_info.block_size,file_info.global_block_offset);
  221.  
  222.     strcpy (buffer,"show");dispatch (buffer);
  223. }
  224.  
  225. void type_file___display (char *command_line)
  226.  
  227. {
  228.     char *ptr,buffer [80];
  229.     
  230.     ptr=parse_word (command_line,buffer);
  231.     if (*ptr==0) 
  232.         strcpy (buffer,"hex");
  233.     else
  234.         ptr=parse_word (ptr,buffer);
  235.     
  236.     if (strcasecmp (buffer,"hex")==0) {
  237.         wprintw (command_win,"Display set to hex\n");wrefresh (command_win);
  238.         file_info.display=HEX;
  239.         sprintf (buffer,"show");dispatch (buffer);
  240.     }
  241.     
  242.     else if (strcasecmp (buffer,"text")==0) {
  243.         wprintw (command_win,"Display set to text\n");wrefresh (command_win);
  244.         file_info.display=TEXT;
  245.         sprintf (buffer,"show");dispatch (buffer);
  246.     }
  247.     
  248.     else {
  249.         wprintw (command_win,"Error - Invalid arguments\n");wrefresh (command_win);
  250.     }
  251. }
  252.  
  253. void file_show_hex (void)
  254.  
  255. {
  256.     long offset=0,l,i;
  257.     unsigned char *ch_ptr;
  258.     
  259.     /* device_offset and type_data points to the inode */
  260.  
  261.     show_pad_info.line=0;
  262.     
  263.     wmove (show_pad,0,0);
  264.     ch_ptr=file_info.buffer;
  265.     for (l=0;l<file_system_info.block_size/16;l++) {
  266.         if (file_info.file_offset+offset>file_info.file_length-1) break;
  267.         wprintw (show_pad,"%08ld :  ",offset);
  268.         for (i=0;i<16;i++) {
  269.             
  270.             if (file_info.file_offset+offset+i>file_info.file_length-1) {
  271.                 wprintw (show_pad," ");
  272.             }
  273.             
  274.             else {
  275.                 if (file_info.offset_in_block==offset+i)
  276.                     wattrset (show_pad,A_REVERSE);
  277.  
  278.                 if (ch_ptr [i]>=' ' && ch_ptr [i]<='z')
  279.                     wprintw (show_pad,"%c",ch_ptr [i]);
  280.                 else
  281.                     wprintw (show_pad,".");
  282.  
  283.                 if (file_info.offset_in_block==offset+i)
  284.                     wattrset (show_pad,A_NORMAL);
  285.             }
  286.         }
  287.  
  288.         wprintw (show_pad,"   ");
  289.         for (i=0;i<16;i++) {
  290.             if (file_info.file_offset+offset+i>file_info.file_length-1) break;
  291.             if (file_info.offset_in_block==offset+i)
  292.                 wattrset (show_pad,A_REVERSE);
  293.  
  294.             wprintw (show_pad,"%02x",ch_ptr [i]);
  295.  
  296.             if (file_info.offset_in_block==offset+i) {
  297.                 wattrset (show_pad,A_NORMAL);
  298.                 show_pad_info.line=l-l % show_pad_info.display_lines;
  299.             }
  300.             
  301.             wprintw (show_pad," ");
  302.             
  303.         }
  304.  
  305.         wprintw (show_pad,"\n");
  306.         offset+=i;
  307.         ch_ptr+=i;
  308.     }
  309.     
  310.     show_pad_info.max_line=l-1;
  311.     
  312.     refresh_show_pad ();
  313.     
  314.     show_status ();
  315. }
  316.  
  317. void file_show_text (void)
  318.  
  319. {
  320.     long offset=0,last_offset,l=0,cols=0;
  321.     unsigned char *ch_ptr;
  322.     
  323.     /* device_offset and type_data points to the inode */
  324.  
  325.     show_pad_info.line=0;
  326.     wmove (show_pad,0,0);
  327.     ch_ptr=file_info.buffer;
  328.  
  329.     last_offset=file_system_info.block_size-1;
  330.  
  331.     if (file_info.file_offset+last_offset > file_info.file_length-1)
  332.         last_offset=file_info.file_length-1-file_info.file_offset;
  333.         
  334.     while ( (offset <= last_offset) && l<SHOW_PAD_LINES) {
  335.  
  336.         if (cols==SHOW_PAD_COLS-1) {
  337.             wprintw (show_pad,"\n");
  338.             l++;cols=0;
  339.         }
  340.         
  341.  
  342.         if (file_info.offset_in_block==offset)
  343.             wattrset (show_pad,A_REVERSE);
  344.  
  345.         if (*ch_ptr >= ' ' && *ch_ptr <= 'z')
  346.             wprintw (show_pad,"%c",*ch_ptr);
  347.  
  348.  
  349.         else {
  350.             if (*ch_ptr == 0xa) {
  351.                 wprintw (show_pad,"\n");
  352.                 l++;cols=0;
  353.             }
  354.  
  355.             else if (*ch_ptr == 0x9)
  356.                 wprintw (show_pad,"    ");
  357.             
  358.             else
  359.                 wprintw (show_pad,".");
  360.         }
  361.  
  362.         if (file_info.offset_in_block==offset) {
  363.             wattrset (show_pad,A_NORMAL);
  364.             show_pad_info.line=l-l % show_pad_info.display_lines;
  365.         }
  366.             
  367.  
  368.         offset++;cols++;ch_ptr++;
  369.     }
  370.     
  371.     wprintw (show_pad,"\n");
  372.     show_pad_info.max_line=l;
  373.     
  374.     refresh_show_pad ();
  375.     
  376.     show_status (); 
  377. }
  378.  
  379. void show_status (void)
  380.  
  381. {
  382.     long inode_num;
  383.     
  384.     werase (show_win);wmove (show_win,0,0);
  385.     wprintw (show_win,"File contents. Block %ld. ",file_info.global_block_num);
  386.     wprintw (show_win,"File block %ld of %ld. ",file_info.block_num,file_info.blocks_count-1);
  387.     wprintw (show_win,"File Offset %ld of %ld.",file_info.file_offset,file_info.file_length-1);
  388.     
  389.     wmove (show_win,1,0);
  390.     inode_num=inode_offset_to_inode_num (file_info.inode_offset);
  391.     wprintw (show_win,"File inode %ld. Indirection level %ld.",inode_num,file_info.level);
  392.  
  393.     refresh_show_win ();
  394. }
  395.  
  396. void type_file___remember (char *command_line)
  397.  
  398. {
  399.     int found=0;
  400.     long entry_num;
  401.     char *ptr,buffer [80];
  402.     struct struct_descriptor *descriptor_ptr;
  403.     
  404.     ptr=parse_word (command_line,buffer);
  405.     
  406.     if (*ptr==0) {
  407.         wprintw (command_win,"Error - Argument not specified\n");wrefresh (command_win);
  408.         return;        
  409.     }
  410.     
  411.     ptr=parse_word (ptr,buffer);
  412.  
  413.     entry_num=remember_lifo.entries_count++;
  414.     if (entry_num>REMEMBER_COUNT-1) {
  415.         entry_num=0;
  416.         remember_lifo.entries_count--;
  417.     }
  418.     
  419.     descriptor_ptr=first_type;
  420.     while (descriptor_ptr!=NULL && !found) {
  421.         if (strcmp (descriptor_ptr->name,"ext2_inode")==0)
  422.             found=1;
  423.         else
  424.             descriptor_ptr=descriptor_ptr->next;
  425.     }
  426.  
  427.  
  428.     remember_lifo.offset [entry_num]=device_offset;
  429.     remember_lifo.type [entry_num]=descriptor_ptr;
  430.     strcpy (remember_lifo.name [entry_num],buffer);
  431.     
  432.     wprintw (command_win,"Object %s in Offset %ld remembered as %s\n",descriptor_ptr->name,device_offset,buffer);
  433.     wrefresh (command_win);
  434. }
  435.  
  436. void type_file___set (char *command_line)
  437.  
  438. {
  439.     unsigned char tmp;
  440.     char *ptr,buffer [80],*ch_ptr;
  441.     int mode=HEX;
  442.     
  443.     ptr=parse_word (command_line,buffer);
  444.     if (*ptr==0) {
  445.         wprintw (command_win,"Error - Argument not specified\n");refresh_command_win ();return;
  446.     }
  447.  
  448.     ptr=parse_word (ptr,buffer);
  449.  
  450.     if (strcasecmp (buffer,"text")==0) {
  451.         mode=TEXT;
  452.         strcpy (buffer,ptr);
  453.     }
  454.  
  455.     else if (strcasecmp (buffer,"hex")==0) {
  456.         mode=HEX;
  457.         ptr=parse_word (ptr,buffer);
  458.     }
  459.  
  460.     if (*buffer==0) {
  461.         wprintw (command_win,"Error - Data not specified\n");refresh_command_win ();return;
  462.     }
  463.  
  464.     if (mode==HEX) {
  465.         do {
  466.             tmp=(unsigned char) strtol (buffer,NULL,16);
  467.             file_info.buffer [file_info.offset_in_block]=tmp;
  468.             file_info.offset_in_block++;
  469.             ptr=parse_word (ptr,buffer);
  470.             if (file_info.offset_in_block==file_system_info.block_size) {
  471.                 if (*ptr) {
  472.                     wprintw (command_win,"Error - Ending offset outside block, only partial string changed\n");
  473.                     refresh_command_win ();
  474.                 }
  475.                 file_info.offset_in_block--;
  476.             }
  477.         } while (*buffer) ;
  478.     }
  479.  
  480.     else {
  481.         ch_ptr=buffer;
  482.         while (*ch_ptr) {
  483.             tmp=(unsigned char) *ch_ptr++;
  484.             file_info.buffer [file_info.offset_in_block]=tmp;
  485.             file_info.offset_in_block++;
  486.             if (file_info.offset_in_block==file_system_info.block_size) {
  487.                 if (*ch_ptr) {
  488.                     wprintw (command_win,"Error - Ending offset outside block, only partial string changed\n");
  489.                     refresh_command_win ();
  490.                 }
  491.                 file_info.offset_in_block--;
  492.             }
  493.         }
  494.     }
  495.     
  496.     strcpy (buffer,"show");dispatch (buffer);
  497. }
  498.  
  499. void type_file___writedata (char *command_line)
  500.  
  501. {
  502.     low_write (file_info.buffer,file_system_info.block_size,file_info.global_block_offset);
  503.     return;
  504. }
  505.  
  506. long file_block_to_global_block (long file_block,struct struct_file_info *file_info_ptr)
  507.  
  508. {
  509.     long last_direct,last_indirect,last_dindirect;
  510.     
  511.     last_direct=EXT2_NDIR_BLOCKS-1;
  512.     last_indirect=last_direct+file_system_info.block_size/4;
  513.     last_dindirect=last_indirect+(file_system_info.block_size/4)*(file_system_info.block_size/4);
  514.  
  515.     if (file_block <= last_direct) {
  516.         file_info_ptr->level=0;
  517.         return (file_info_ptr->inode_ptr->i_block [file_block]);
  518.     }
  519.     
  520.     if (file_block <= last_indirect) {
  521.         file_info_ptr->level=1;
  522.         file_block=file_block-last_direct-1;
  523.         return (return_indirect (file_info_ptr->inode_ptr->i_block [EXT2_IND_BLOCK],file_block));
  524.     }
  525.  
  526.     if (file_block <= last_dindirect) {
  527.         file_info_ptr->level=2;
  528.         file_block=file_block-last_indirect-1;
  529.         return (return_dindirect (file_info_ptr->inode_ptr->i_block [EXT2_DIND_BLOCK],file_block));
  530.     }
  531.  
  532.     file_info_ptr->level=3;
  533.     file_block=file_block-last_dindirect-1;
  534.     return (return_tindirect (file_info_ptr->inode_ptr->i_block [EXT2_TIND_BLOCK],file_block));
  535. }
  536.  
  537. long return_indirect (long table_block,long block_num)
  538.  
  539. {
  540.     long block_table [EXT2_MAX_BLOCK_SIZE/4];
  541.     
  542.     low_read ((char *) block_table,file_system_info.block_size,table_block*file_system_info.block_size);
  543.     return (block_table [block_num]);        
  544. }
  545.  
  546. long return_dindirect (long table_block,long block_num)
  547.  
  548. {
  549.     long f_indirect;
  550.     
  551.     f_indirect=block_num/(file_system_info.block_size/4);
  552.     f_indirect=return_indirect (table_block,f_indirect);
  553.     return (return_indirect (f_indirect,block_num%(file_system_info.block_size/4)));
  554. }
  555.  
  556. long return_tindirect (long table_block,long block_num)
  557.  
  558. {
  559.     long s_indirect;
  560.     
  561.     s_indirect=block_num/((file_system_info.block_size/4)*(file_system_info.block_size/4));
  562.     s_indirect=return_indirect (table_block,s_indirect);
  563.     return (return_dindirect (s_indirect,block_num%((file_system_info.block_size/4)*(file_system_info.block_size/4))));
  564. }
  565.